// SKNotes - a note taking and gathering tool
// Copyright (C) 2009  Stefan Kueng
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

namespace SKNotes.Configuration
{
    using System;
    using System.Windows;
    using System.Diagnostics;

	public class PropertySettingCollector : SettingCollector
	{
		public PropertySettingCollector( FrameworkElement owner, Type elementType, string propertyName )
		{
			if ( owner == null )
			{
				throw new ArgumentNullException( "owner" );
			}
			if ( elementType == null )
			{
				throw new ArgumentNullException( "elementType" );
			}
			if ( string.IsNullOrEmpty( propertyName ) )
			{
				throw new ArgumentNullException( "propertyName" );
			}

			this.owner = owner;
			this.elementType = elementType;
			this.propertyName = propertyName;
		} 

		public FrameworkElement Owner
		{
			get { return this.owner; }
		} 

		public Type ElementType
		{
			get { return this.elementType; }
		} 

		public string PropertyName
		{
			get { return this.propertyName; }
		}

		public override void Collect()
		{
			Collect( this.owner, true );
		} 

		private void Collect( DependencyObject currentObject, bool recursive )
		{
			foreach ( object child in LogicalTreeHelper.GetChildren( currentObject ) )
			{
				DependencyObject dependencyObject = child as DependencyObject;
				if ( dependencyObject == null )
				{
					continue;
				}

				FrameworkElement frameworkElement = child as FrameworkElement;
				if ( frameworkElement != null )
				{
					bool add = this.elementType.IsAssignableFrom( frameworkElement.GetType() );

					if ( add && string.IsNullOrEmpty( frameworkElement.Name ) )
					{
						add = false;
						Debug.WriteLine( "PropertySettingCollector: missing name for framework element " + frameworkElement );
					}

					if ( add && !OnCollectingSetting( frameworkElement ) )
					{
						add = false;
					}

					if ( add )
					{
						string settingName = string.Concat( frameworkElement.Name, ".", this.propertyName );
						PropertySetting propertySetting = new PropertySetting( settingName, frameworkElement, this.propertyName );
						propertySetting.DefaultValue = propertySetting.Value;
						ApplicationSettings.Settings.Add( propertySetting );
					}
				}

				if ( recursive )
				{
					Collect( dependencyObject, true );
				}
			}
		}

		private readonly FrameworkElement owner;
		private readonly Type elementType;
		private readonly string propertyName;

	}
}
